#include "battery_yjt.h"

Battery_YJT::Battery_YJT(QObject* parent) : QObject(parent) {}

//打开电池CAN设备
bool Battery_YJT::CanOpenAndStart() {
  DWORD dwRel;
  dw_DeviceHandle = CAN_DeviceOpen(LCMiniPcie_432, dw_Index, nullptr);
  if (dw_DeviceHandle == 0) { return false; }
  // 配置CAN通道参数
  CAN_InitConfig config;
  config.dwAccCode = 0;
  config.dwAccMask = 0xffffffff;
  config.nFilter = 0;         // 滤波方式(0表示未设置滤波功能,1表示双滤波,2表示单滤波)
  config.bMode = 0;           // 工作模式(0表示正常模式,1表示只听模式)
  config.nBtrType = 1;        // 位定时参数模式(1表示SJA1000,0表示LPC21XX)
  config.dwBtr[0] = dw_Btr0;  // BTR0   0014 -1M 0016-800K 001C-500K 011C-250K
                              // 031C-125K 041C-100K 091C-50K 181C-20K 311C-10K
                              // BFFF-5K
  config.dwBtr[1] = dw_Btr1;  // BTR1
  config.dwBtr[2] = 0;
  config.dwBtr[3] = 0;

  dwRel = CAN_ChannelStart(dw_DeviceHandle, dw_Channel, &config);
  if (dwRel != CAN_RESULT_OK) { return false; }
  is_open_can = true;
  return true;
}

//关闭电池CAN设备
bool Battery_YJT::CanStopAndClose() {
  if (is_open_can) {
    CAN_ChannelStop(dw_DeviceHandle, dw_Channel);
    if (CAN_DeviceClose(dw_DeviceHandle) == CAN_RESULT_OK) {
      is_open_can = false;
      qDebug() << "CAN关闭成功";
      return true;
    }
  }
  return false;
}

void Battery_YJT::charge(bool enable) {
  CAN_DataFrame frames[1];
  frames[0].uID = 0x160;
  frames[0].nSendType = 0;
  frames[0].bRemoteFlag = 0;
  frames[0].bExternFlag = 0;
  frames[0].nDataLen = 1;
  frames[0].arryData[0] = enable ? 0x1 : 0x0;
  CanSendData(frames, 1);
}

//订阅接收CAN数据  CAN数据为自动上报
bool Battery_YJT::CanReceiveData() {
  if (!is_open_can) { return false; }

  ULONG dwRel;
  CAN_DataFrame vco[100];
  dwRel = CAN_ChannelReceive(dw_DeviceHandle, dw_Channel, vco, 200, 40);
  if (dwRel > 0) {
    for (ULONG i = 0; i < dwRel; i++) {
      QByteArray recv;
      for (int k = 0; k < vco[i].nDataLen; k++) { recv.append(static_cast<char>(vco[i].arryData[k])); }
      emit sigShowCanData(recv, "Recv:" + QString::number(vco[i].uID, 16));  //发送打印

      switch (vco[i].uID) {
        case 0x1E1:
          battery_data.total_vol = 0.1 * static_cast<uint16_t>((vco[i].arryData[0] << 8) + vco[i].arryData[1]);
          battery_data.total_cur = 0.1 * static_cast<uint16_t>((vco[i].arryData[2] << 8) + vco[i].arryData[3]) - 1000;
          battery_data.soc = 0.1 * static_cast<uint16_t>((vco[i].arryData[4] << 8) + vco[i].arryData[5]);
          break;
        case 0x352:
          battery_data.max_singel_vol = 0.001 * static_cast<uint16_t>((vco[i].arryData[0] << 8) + vco[i].arryData[1]);
          battery_data.max_singel_vol_num = static_cast<uint16_t>((vco[i].arryData[2] << 8) + vco[i].arryData[3]);
          battery_data.min_singel_vol = 0.001 * static_cast<uint16_t>((vco[i].arryData[4] << 8) + vco[i].arryData[5]);
          battery_data.min_singel_vol_num = static_cast<uint16_t>((vco[i].arryData[6] << 8) + vco[i].arryData[7]);
          break;
        case 0x353:
          battery_data.max_temp = static_cast<int8_t>(vco[i].arryData[0]) - 50;
          battery_data.max_temp_num = static_cast<uint16_t>((vco[i].arryData[1] << 8) + vco[i].arryData[2]);
          battery_data.min_temp = static_cast<int8_t>(vco[i].arryData[3]) - 50;
          battery_data.min_temp_num = static_cast<uint16_t>((vco[i].arryData[4] << 8) + vco[i].arryData[5]);
          break;
        case 0x1E4:
          battery_data.charge_relay_state = (vco[i].arryData[0] >> 5) & 0b1;
          battery_data.charge_state = static_cast<ChargeState>((vco[i].arryData[0] >> 6) & 0b11);
          break;
      }
    }
  }
  return 0;
}

// CAN发送电池数据
void Battery_YJT::CanSendData(PCAN_DataFrame frames, ULONG i) {
  if (i == 0) return;
  CAN_ChannelSend(dw_DeviceHandle, dw_Channel, frames, i);

  //发送打印  UPDATE 2022.10.28 can发送不打印，减少卡机
  //    for ( ULONG j = 0; j < i; j++ ) {
  //        QByteArray demo;
  //        for ( int k = 0; k < frames[ j ].nDataLen; k++ ) {
  //            demo.append( static_cast< char >( frames[ j ].arryData[ k ] ) );
  //        }
  //        emit sigShowCanData( demo, "Send:" + QString::number( frames[ j
  //        ].uID, 16 ) );
  //    }
}

Battery_YJT::BatteryData_YJT Battery_YJT::getBatteryData() const { return battery_data; }

void Battery_YJT::sltCanBatteryInit() {
  if (CanOpenAndStart()) {
    emit sigSendTips("正确，电池CAN设备打开成功！");
  } else {
    emit sigSendTips("错误，电池CAN设备打开失败！");
    return;
    qDebug() << "调试---一删除";
  }

  QTimer* timer100ms = new QTimer();
  connect(timer100ms, SIGNAL(timeout()), this, SLOT(sltTimeout_battery()));
  timer100ms->start(100);
}

void Battery_YJT::sltTimeout_battery() {
  if (!is_open_can) { return; }

  //定期接收
  CanReceiveData();
}
